package com.vframework.common.response;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonView;
import com.vframework.common.response.enums.ReturnEnum;
import com.vframework.common.response.jsonview.GeneralViews;
import com.vframework.exception.BaseException;
import lombok.Data;
import lombok.Getter;
import lombok.ToString;
import org.springframework.dao.DataAccessException;
import org.springframework.util.StringUtils;

import java.io.Serializable;
import java.sql.SQLException;

/**
 * @author zt_sh
 */
@Data
@ToString
public class R<T> implements Serializable {

	@Getter(onMethod = @__(@JsonView(GeneralViews.SimpleView.class)))
	private String resultCode;

	@Getter(onMethod = @__(@JsonView(GeneralViews.SimpleView.class)))
	private String resultMsg;

	/**
	 *  @JsonInclude(JsonInclude.Include.NON_NULL) 为空时候不返回
	 */
	@Getter(onMethod = @__(@JsonView(GeneralViews.SimpleView.class)))
	@JsonInclude(JsonInclude.Include.NON_NULL)
	private T data;

	/**
	 * 成功，不返回具体数据，不自定义返回内容
	 * @return
	 */
	public static R success() {
		R result = new R();
		result.setResultCode(ReturnEnum.SUCCESS.getCode());
		result.setResultMsg(ReturnEnum.SUCCESS.getMsg());
		return result;
	}

	/**
	 * 成功，不返回具体数据，自定义返回内容
	 * @param msg
	 * @return
	 */
	public static R success(String msg) {
		R result = new R();
		result.setResultCode(ReturnEnum.SUCCESS.getCode());
		result.setResultMsg(msg);
		return result;
	}

	/**
	 * 成功，返回具体数据，不自定义返回内容
	 * @param <T>
	 * @return
	 */
	public static <T> R<T> success(T t) {
		R<T> result = new R<>();
		result.setResultCode(ReturnEnum.SUCCESS.getCode());
		result.setResultMsg(ReturnEnum.SUCCESS.getMsg());
		result.setData(t);
		return result;
	}

	/**
	 * 返回失败的情况下，必须定义返回内容
	 *
	 * @return
	 */
	@Deprecated
	public static R fail() {
		return fail(ReturnEnum.FAIL);
	}

	/**
	 * 失败，自定义返回内容
	 * @return
	 */
	public static R fail(ReturnEnum returnEnum) {
		R result = new R();
		result.setResultCode(returnEnum.getCode());
		result.setResultMsg(returnEnum.getMsg());
		return result;
	}

	public static R fail(Exception e) {
		R result;
		if (e instanceof BaseException) {
			BaseException ex = (BaseException) e;
			result = fail(ex.getResultEnum());
		} else if (e instanceof DataAccessException) {
			result = fail(ReturnEnum.DATA_ACCESS_ERROR);
		} else if (e instanceof SQLException) {
			result = fail(ReturnEnum.DATA_ACCESS_ERROR);
		} else {
			String message = e != null ? e.getMessage() : ReturnEnum.FAIL.getMsg();
			result = fail(ReturnEnum.FAIL);
			if (!StringUtils.isEmpty(message)) {
				result.setResultMsg(message);
			}
		}
		return result;
	}
}
